#pragma once
#include <atomic>
#include <map>
#include <memory>
#include <string>
#include "XnccType.h"
namespace xncc {
namespace foundation {
    class Poller;
    class WakeupChannel;
    class TimerChannel;
    /// 不对外提供定时器函数
    /// 不对外提供回调注册
    class EventLoop
    {
      public:
        EventLoop(types::thread_id_t id, const std::string& name, types::IO_MULTI_MODE::value mode);
        ~EventLoop();

        EventLoop(const EventLoop&)             = delete;
        EventLoop(const EventLoop&&)            = delete;
        EventLoop& operator=(const EventLoop&)  = delete;
        EventLoop& operator=(const EventLoop&&) = delete;

        void               init(bool isIpcLoop);
        [[nodiscard]] auto id() const -> types::thread_id_t { return id_; }
        [[nodiscard]] auto mode() const -> types::IO_MULTI_MODE::value;
        [[nodiscard]] auto name() const -> const std::string& { return name_; }
        void               stop() { exit_ = true; }
        [[nodiscard]] auto coreID() const -> int32_t { return coreId_; }
        void               setCoreId(int32_t coreId) { coreId_ = coreId; }
        Poller*            poller();
        [[nodiscard]] auto getUserFuncs() const -> const std::map<types::message_id_t, types::UserFunc>&
        {
            return userRegFuncs_;
        }
        void registerUserFunc(types::message_id_t id, types::UserFunc cb);

        // 取消定时任务，若timer已经过期，则忽略
        void cancel(types::timer_id_t timerid);
        // 添加定时任务，interval=0表示一次性任务，否则为重复任务，时间为微妙
        ///
        types::timer_id_t runAt(int64_t mcroSecs, types::Task task, int64_t interval = 0);
        types::timer_id_t runAfter(int64_t mcroSecs, types::Task task, int64_t interval = 0);

        [[nodiscard]] int  status() const;
        void               loop(int waitUs);                                        // 开始循环
        void               runInLoop(types::Task cb);                               // 把任务放到循环中执行
        void               assertInLoopThread(const std::string& func_name) const;  // 判断是不是在循环线程中
        [[nodiscard]] bool isInLoopThread() const;                                  // 判断是不是在循环线程中

      private:
        const types::thread_id_t                       id_;
        const std::string                              name_;
        std::unique_ptr<Poller>                        poller_;        // 先声明后析构
        std::map<types::message_id_t, types::UserFunc> userRegFuncs_;  /// 用户在这个线程上注册的回调函数集合
        std::shared_ptr<TimerChannel>                  timerChannel_;
        int32_t                                        coreId_;
        std::shared_ptr<WakeupChannel> wakeupChannel_;  // 必须用shared_ptr，init操作的时候 需要 add this
        std::atomic<bool>              exit_      = {false};
        pid_t                          threadId_  = {0};
        int                            status_    = {0};
        bool                           isIpcLoop_ = {false};
    };
}  // namespace foundation
}  // namespace xncc